import React, { memo, useCallback, useEffect, useRef, useMemo } from 'react';

export const withPerformance = <P extends object>(
  Component: React.ComponentType<P>,
  options: {
    memoize?: boolean;
    customComparison?: (prevProps: P, nextProps: P) => boolean;
  } = {}
) => {
  const { memoize = true, customComparison } = options;

  // 优化 memo 比较，提供默认的浅比较
  const WrappedComponent = memoize
    ? memo(Component, customComparison)
    : Component;

  // 设置显示名称便于调试
  if (memoize) {
    WrappedComponent.displayName = `withPerformance(${Component.displayName || Component.name})`;
  }

  return WrappedComponent;
};

export const usePerformanceMonitor = (componentName: string) => {
  const renderCount = useRef(0);
  const renderTime = useRef<number[]>([]);
  const lastRenderTime = useRef<number | null>(null);

  // 使用 useMemo 缓存平均渲染时间计算结果
  const averageRenderTime = useMemo(() => {
    if (renderTime.current.length === 0) return 0;
    return renderTime.current.reduce((a, b) => a + b, 0) / renderTime.current.length;
  }, [renderTime.current.length]);

  useEffect(() => {
    renderCount.current += 1;
    const currentTime = performance.now();

    if (lastRenderTime.current !== null) {
      const renderDuration = currentTime - lastRenderTime.current;
      renderTime.current.push(renderDuration);

      if (renderTime.current.length > 10) {
        renderTime.current.shift();
      }

      if (renderDuration > 100) {
        console.warn(`[Performance] ${componentName} 渲染时间过长: ${renderDuration.toFixed(2)}ms`);
      }
    }

    lastRenderTime.current = currentTime;
  }, []);

  // 使用 useMemo 缓存返回的对象，避免每次都返回新对象
  return useMemo(() => ({
    renderCount: renderCount.current,
    averageRenderTime,
    renderTimes: renderTime.current
  }), [averageRenderTime]);
};

export const useDebounce = <T extends (...args: any[]) => any>(
  callback: T,
  delay: number
): T => {
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);

  return useCallback(
    ((...args: Parameters<T>) => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }

      timeoutRef.current = setTimeout(() => {
        callback(...args);
      }, delay);
    }) as T,
    [callback, delay]
  );
};

export const useThrottle = <T extends (...args: any[]) => any>(
  callback: T,
  delay: number
): T => {
  const lastCallTime = useRef<number>(0);

  return useCallback(
    ((...args: Parameters<T>) => {
      const now = Date.now();
      if (now - lastCallTime.current >= delay) {
        callback(...args);
        lastCallTime.current = now;
      }
    }) as T,
    [callback, delay]
  );
};

export interface PerformanceMonitorProps {
  componentName: string;
  enabled?: boolean;
}

export const PerformanceMonitor: React.FC<PerformanceMonitorProps> = ({ componentName, enabled = true }) => {
  const { renderCount, averageRenderTime, renderTimes } = usePerformanceMonitor(componentName);

  if (!enabled) {
    return null;
  }

  const latestRenderTime = renderTimes.length > 0 ? renderTimes[renderTimes.length - 1] : 0;

  return React.createElement('div', {
    style: {
      position: 'fixed',
      bottom: '10px',
      right: '10px',
      background: 'rgba(0,0,0,0.7)',
      color: 'white',
      padding: '10px',
      borderRadius: '5px',
      fontSize: '12px',
      zIndex: 9999
    }
  }, [
    React.createElement('div', { key: 'title' }, `${componentName} 性能监控`),
    React.createElement('div', { key: 'count' }, `渲染次数: ${renderCount}`),
    React.createElement('div', { key: 'avg' }, `平均渲染时间: ${averageRenderTime.toFixed(2)}ms`),
    React.createElement('div', { key: 'latest' }, `最近渲染时间: ${latestRenderTime.toFixed(2)}ms`)
  ]);
};